package deformation;



import java.util.Observable;
import java.util.Observer;

import grid.AbstractGridFactory;
import grid.Grid;
import grid.GridFactoryListener;
import handler.Handler;

final class MorphingGrid_Impl <T extends PreCompute> extends AbstractGridFactory implements  Observer, MorphingGrid{

	
	private final Grid father;
	private final Handler handler;
	private final T[] precomputed;
	private final AbstractDeformation<T> deformation;
	private long deformationStatus =0;
	MorphingGrid_Impl(Grid father, Handler handler,
			T[] precomputed, AbstractDeformation<T> deformation) {
		this.father = father;
		this.handler = handler;
		this.precomputed = precomputed;
		this.deformation = deformation;
	}
	
	

	


	public Grid getFatherGrid() {
		return father;
	}

	public Deformation getDeformation() {
		return deformation;
	}

	@Override
	protected Grid generateNewGrid() {
		this.deformationStatus = handler.getDeformationStatus();
		return deformation.calculate(father, precomputed);
	}


	@Override
	public boolean gridHasChanged() {
		return deformationStatus != handler.getDeformationStatus();
	}

	
	@Override
	public synchronized void addGridFactoryListener(GridFactoryListener listener) {
		super.addGridFactoryListener(listener);
		if (countGridFactoryListener()>0) {
			handler.addObserver(this);
		}
	}
	
	@Override
	public void removeGridFactoryListener(GridFactoryListener listener) {
		super.removeGridFactoryListener(listener);
		if (countGridFactoryListener()==0) {
			handler.deleteObserver(this);
		}
	}





	@Override
	public void update(Observable o, Object arg) {
		if (o == handler) {
			notifyGridFactoryListener();
		}else {
			o.deleteObserver(this);
		}
		
	}
	
	

}
